﻿using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using Framework.Data.Exceptions;
using Framework.Data.Core;
/// <summary>
/// Module qui regroupe des fonctions de validation générique
/// </summary>
/// <remarks></remarks>
/// 
namespace Framework.Data.Utilities
{
    public static class Validation
    {

        /// <summary>
        /// Procédure qui vérifie s'il n'y a pas chevauchement entre les Taux_Changes
        /// </summary>
        /// <param name="brokenRules">Conteneur à exception</param>
        /// <param name="container">Conteneur d'élément à valider</param>
        /// <param name="peutEtreMemeJour">Indique si la date de début et de fin peuvent être le même jour</param> 
        /// <remarks></remarks>
        public static void ValiderChevauchementDate(List<AppException> brokenRules, ChildrenContainer container, bool peutEtreMemeJour = true)
        {
            bool result = false;
            List<IBaseEntity> lstEntity = null;
            IDateDebutDateFin date1 = null;
            IDateDebutDateFin date2 = null;
            //On valide seulement si le container est chargé
            if (container.IsLoaded)
            {
                lstEntity = container.ToArrayList();
                for (Int32 i = 0; i <= lstEntity.Count - 2; i++)
                {
                    for (Int32 j = i + 1; j <= lstEntity.Count - 1; j++)
                    {
                        date1 = (IDateDebutDateFin)lstEntity[i];
                        date2 = (IDateDebutDateFin)lstEntity[j];
                        result = ValiderChevauchementDate(date1, date2, peutEtreMemeJour);
                        if (result)
                            break; // TODO: might not be correct. Was : Exit For
                    }
                    if (result)
                        break; // TODO: might not be correct. Was : Exit For
                }
            }

            if (result)
            {
                AppException ex = new AppException("MSG_CHEVAUCHEMENT_DATE");
                ex.Parameters.Add(new AppExceptionParameter(date1.ToString(), AppExceptionParameter.eParameterType.Value));
                ex.Parameters.Add(new AppExceptionParameter(date2.ToString(), AppExceptionParameter.eParameterType.Value));
                brokenRules.Add(ex);
            }

        }

        /// <summary>
        /// Fonction qui valide si 2 entités se chevauche l'un l'autre
        /// </summary>
        /// <param name="entity1">Première entité</param>
        /// <param name="entity2">Deuxième entité</param>
        /// <param name="peutEtreMemeJour">Indique si la date de début et de fin peuvent être le même jour</param>
        /// <returns>Boolean</returns>
        /// <remarks></remarks>
        public static bool ValiderChevauchementDate(IDateDebutDateFin entity1, IDateDebutDateFin entity2, bool peutEtreMemeJour = true)
        {

            if ((!entity1.MarkAsDeleted) & (!entity2.MarkAsDeleted))
            {
                if (entity1.DateFin.Ticks == 0)
                {
                    //Si les dates de fin sont à l'infini, il y a chevauchement
                    if (entity2.DateFin.Ticks == 0)
                    {
                        return true;
                    }
                    else
                    {
                        //Si la date de début du date1 est entre les dates du date2, il y a chevauchement
                        if (peutEtreMemeJour)
                        {
                            if (entity1.DateDebut.Date < entity2.DateFin.Date)
                            {
                                return true;
                            }
                        }
                        else
                        {
                            if (entity1.DateDebut.Date <= entity2.DateFin.Date)
                            {
                                return true;
                            }
                        }

                    }
                }
                else if (entity2.DateFin.Ticks == 0)
                {
                    //Si la date de début du date2 est entre les dates du date1, il y a chevauchement
                    if (peutEtreMemeJour)
                    {
                        if (entity2.DateDebut.Date < entity1.DateFin.Date)
                        {
                            return true;
                        }
                    }
                    else
                    {
                        if (entity2.DateDebut.Date <= entity1.DateFin.Date)
                        {
                            return true;
                        }
                    }
                }
                else
                {
                    //Si la date de début du date1 est entre les dates du date2, il y a chevauchement
                    if (peutEtreMemeJour)
                    {
                        if (entity1.DateDebut.Date >= entity2.DateDebut.Date & entity1.DateDebut.Date < entity2.DateFin.Date)
                        {
                            return true;
                        }
                    }
                    else
                    {
                        if (entity1.DateDebut.Date >= entity2.DateDebut.Date & entity1.DateDebut.Date <= entity2.DateFin.Date)
                        {
                            return true;
                        }
                    }
                    //Si la date de début du date2 est entre les dates du date1, il y a chevauchement
                    if (peutEtreMemeJour)
                    {
                        if (entity2.DateDebut.Date >= entity1.DateDebut.Date & entity2.DateDebut.Date < entity1.DateFin.Date)
                        {
                            return true;
                        }
                    }
                    else
                    {
                        if (entity2.DateDebut.Date >= entity1.DateDebut.Date & entity2.DateDebut.Date <= entity1.DateFin.Date)
                        {
                            return true;
                        }
                    }
                }
            }

            return false;
        }


        /// <summary>
        /// Procédure qui vérifie s'il n'y a pas chevauchement date pour une même entité
        /// </summary>
        /// <remarks></remarks>
        public static void ValiderChevauchementDateEntite(List<AppException> brokenRules, ChildrenContainer container)
        {
            bool result = false;
            List<IBaseEntity> lstEntity = null;
            IDateDebutDateFinEntite date1 = null;
            IDateDebutDateFinEntite date2 = null;
            //On valide seulement si le container est chargé
            if (container.IsLoaded)
            {
                lstEntity = container.ToArrayList();
                for (Int32 i = 0; i <= lstEntity.Count - 2; i++)
                {
                    for (Int32 j = i + 1; j <= lstEntity.Count - 1; j++)
                    {
                        date1 = (IDateDebutDateFinEntite)lstEntity[i];
                        date2 = (IDateDebutDateFinEntite)lstEntity[j];
                        result = ValiderChevauchementDateEntite(date1, date2);
                        if (result)
                            break; // TODO: might not be correct. Was : Exit For
                    }
                    if (result)
                        break; // TODO: might not be correct. Was : Exit For
                }
            }

            if (result)
            {
                AppException ex = new AppException("MSG_CHEVAUCHEMENT_DATE");
                ex.Parameters.Add(new AppExceptionParameter(date1.ToString(), AppExceptionParameter.eParameterType.Value));
                ex.Parameters.Add(new AppExceptionParameter(date2.ToString(), AppExceptionParameter.eParameterType.Value));
                brokenRules.Add(ex);
            }

        }

        /// <summary>
        /// Fonction qui valide si 1 entités se chevauche 
        /// </summary>
        /// <param name="entity1">Première entité</param>
        /// <param name="entity2">Deuxième entité</param>
        /// <returns>Boolean</returns>
        /// <remarks></remarks>
        public static bool ValiderChevauchementDateEntite(IDateDebutDateFinEntite entity1, IDateDebutDateFinEntite entity2)
        {

            if ((!entity1.MarkAsDeleted) & (!entity2.MarkAsDeleted))
            {
                //On compare les dates seulement si les id sont identiques

                if (entity2.IdCle == entity1.IdCle)
                {
                    if (entity1.DateFin.Ticks == 0)
                    {
                        //Si les dates de fin sont à l'infini, il y a chevauchement
                        if (entity2.DateFin.Ticks == 0)
                        {
                            return true;
                        }
                        else
                        {
                            //Si la date de début du date1 est entre les dates du date2, il y a chevauchement
                            if (entity1.DateDebut.Date < entity2.DateFin.Date)
                            {
                                return true;
                            }
                        }
                    }
                    else if (entity2.DateFin.Ticks == 0)
                    {
                        //Si la date de début du date2 est entre les dates du date1, il y a chevauchement
                        if (entity2.DateDebut.Date < entity1.DateFin.Date)
                        {
                            return true;
                        }
                    }
                    else
                    {
                        //Si la date de début du date1 est entre les dates du date2, il y a chevauchement
                        if (entity1.DateDebut.Date >= entity2.DateDebut.Date & entity1.DateDebut.Date < entity2.DateFin.Date)
                        {
                            return true;
                        }
                        //Si la date de début du date2 est entre les dates du date1, il y a chevauchement
                        if (entity2.DateDebut.Date >= entity1.DateDebut.Date & entity2.DateDebut.Date < entity1.DateFin.Date)
                        {
                            return true;
                        }
                    }
                }
            }

            return false;
        }


    }
}